package net.obxlabs.tweetpad.behaviour;

import penner.easing.*;
import net.nexttext.Locatable;
import net.nexttext.TextObject;
import net.nexttext.Vector3;
import net.nexttext.Vector3ArithmeticException;
import net.nexttext.behaviour.AbstractAction;
import net.nexttext.behaviour.TargetingAction;
import net.nexttext.property.*;

/**
 * Move an object to the location.
 * 
 * $Id:EaseTo.java 16 2007-11-27 10:50:46Z prisonerjohn $
 */
public class EaseTo extends AbstractAction {
    public EaseTo() {
    }

    /**
     * Computes the position of the TextObject using Robert Penner's easing equations.
     *
     * <p>Result is complete if the TextObject has reached its target.</p>
     */
    public ActionResult behave(TextObject to) {
    	BooleanProperty easeSwitchProp;
    	if ((easeSwitchProp = (BooleanProperty)to.getProperty("EaseSwitch")) == null) {
    		// there is nothing to do
        	return new ActionResult(true, true, false);
    	}
        if (easeSwitchProp.get()) {
        	// get all the data
        	float currTime = (float)((NumberProperty)to.getProperty("EaseCurrTime")).get();
       		Vector3 start = ((Vector3Property)to.getProperty("EaseStart")).get();
       		Vector3 offset = ((Vector3Property)to.getProperty("EaseOffset")).get();
       		float duration = (float)((NumberProperty)to.getProperty("EaseDuration")).get();
       		
       		// calculate and set the new positions
       		float newX = Expo.easeOut(currTime, (float)start.x, (float)offset.x, duration);
       		float newY = Expo.easeOut(currTime, (float)start.y, (float)offset.y, duration);
       		to.getPosition().set(new Vector3(newX, newY));
       		
       		if (currTime < duration) {
       			// set up the next iteration
           		currTime++;
       			((NumberProperty)to.getProperty("EaseCurrTime")).set(currTime);
       			return new ActionResult(false, true, false);
       		} else {
       			// the animation is complete
       			easeSwitchProp.set(false);
       			return new ActionResult(true, true, false);
       		}
        } else {
        	// there is nothing to do
        	return new ActionResult(true, true, false);
        }
    }

    /**
     * Sets up a new animation.
     */
    public static void setAnim(TextObject to, Locatable offset, int duration) {
       	
       	if (to.getProperty("EaseSwitch") == null) {
       		// the properties have not been initialized yet, create them
       		to.init("EaseCurrTime", new NumberProperty(0));
       		to.init("EaseStart", new Vector3Property(to.getPosition().get()));
       		to.init("EaseOffset", new Vector3Property(offset.getLocation()));
       		to.init("EaseDuration", new NumberProperty(duration));
       		to.init("EaseSwitch", new BooleanProperty(true));
       	} else {
       		// the properties already exist, modify them
       		((NumberProperty)to.getProperty("EaseCurrTime")).set(0);
       		((Vector3Property)to.getProperty("EaseStart")).set(to.getPosition().get());
       		((Vector3Property)to.getProperty("EaseOffset")).set(offset.getLocation());
       		((NumberProperty)to.getProperty("EaseDuration")).set(duration);
       		((BooleanProperty)to.getProperty("EaseSwitch")).set(true);
       	}
    }
}
